﻿namespace CloudNinja.Metering.Tests.ODataController
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using CloudNinja.Metering.Data;
    using CloudNinja.Metering.Data.Dapper;
    using CloudNinja.Metering.Data.Models;
    using CloudNinja.Metering.Tests.DataRepository;
    using CloudNinja.Metering.Web.Controllers;

    using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;

    using Xunit;

    public class ODataControllerTests : MeteringRepositoryFixture
    {
        private readonly IMeteringReporting reportingRepository;

        private readonly IMeteringDataRepository meteringRepository;

        public ODataControllerTests()
        {
            var repository = new MeteringDataRepository("Data Source=.; Initial Catalog=cnmb; Integrated Security=SSPI;", this.sqlRetryPolicy);
            this.reportingRepository = repository;
            this.meteringRepository = repository;
        }

        [Fact]
        public void CanGetMonthlyView()
        {
            var monthlyViewController = new MonthlyViewController(this.reportingRepository);

            this.RemoveMeterData();

            var results = monthlyViewController.Get().Result.ToList();

            Assert.False(results.Any(meterData => meterData.TenantId.Contains("testtenant")));

            this.AddMeterDataForSameTenantForTwoDays();

            results = monthlyViewController.Get().Result.ToList();

            Assert.Equal(2, results.Count(meterData => meterData.TenantId.Contains("testtenant")));
        }

        [Fact]
        public void CanWriteMeterData()
        {
            var meterDataController = new MeterDataRepositoryController(this.meteringRepository);

            this.RemoveMeterData();

            this.AddMeterDataForSameTenantForTwoDays();
            var meterData = this.GetTestMeterData();
            Assert.Equal(2, meterData.Count(d => d.TenantId.Contains("testtenant")));

            // Force to run sync, and add data for a month earlier.
            var postResult = meterDataController.Post(
                new MeterData
                    {
                        MeterTypeId = "bwe",
                        TenantId = "testtenant1",
                        TimePeriod = DateTime.Now.AddMonths(-1),
                        Count = 1,
                        Value = 2.2
                    }).Result;
            meterData = this.GetTestMeterData();
            Assert.Equal(3, meterData.Count(d => d.TenantId.Contains("testtenant")));

            this.RemoveMeterData();
        }

        [Fact]
        public void CanGetTotalResourceUsage()
        {
            var totalResourceUsageController = new TotalResourceUsageController(this.reportingRepository);

            this.RemoveMeterData();

            var results = totalResourceUsageController.Get().Result.ToList();

            Assert.False(results.Any(d => d.TenantId.Contains("testtenant")));

            this.AddMeterDataForSameTenantForTwoDays();

            results = totalResourceUsageController.Get().Result.ToList();

            Assert.Equal(1, results.Count(d => d.TenantId.Contains("testtenant")));

            Assert.Equal(1, results[0].TotalBwe);
            Assert.Equal(1, results[0].TotalDbs);

            this.RemoveMeterData();
        }

        [Fact]
        public void CanGetMeterData()
        {
            var totalResourceUsageController = new MeterDataController(this.reportingRepository);

            this.RemoveMeterData();

            var results = totalResourceUsageController.Get().Result.ToList();

            Assert.False(results.Any(d => d.TenantId.Contains("testtenant")));

            this.AddMeterDataForSameTenantForTwoDays();

            results = totalResourceUsageController.Get().Result.ToList();

            Assert.Equal(2, results.Count(d => d.TenantId.Contains("testtenant")));

            this.RemoveMeterData();
        }

        [Fact]
        public void CanGetTotalDailyView()
        {
            var totalResourceUsageController = new TotalDailyViewController(this.reportingRepository);

            this.RemoveMeterData();

            this.AddMeterDataForSameTenantForTwoDays();

            var results = totalResourceUsageController.Get().Result.ToList();

            Assert.True(results.Any());

            this.RemoveMeterData();
        }

        [Fact]
        public void CanGetTotalMonthlyView()
        {
            var totalResourceUsageController = new TotalMonthlyViewController(this.reportingRepository);

            this.RemoveMeterData();

            this.AddMeterDataForSameTenantForTwoDays();

            var results = totalResourceUsageController.Get().Result.ToList();

            Assert.True(results.Any());

            this.RemoveMeterData();
        }
    }
}
